package cn.cybozu.api;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;



public class KintoneRecord
{
	private Long id;
	private Long revision;
	private Map<String, Object> fields = new LinkedHashMap<String, Object>();
	private Map<String, KintoneSubTable> subTables = new LinkedHashMap<String, KintoneSubTable>();
	
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public Long getRevision()
	{
		return revision;
	}
	public void setRevision(Long revision)
	{
		this.revision = revision;
	}
	public void setNull(String fieldCode)
	{
		fields.put(fieldCode, null);
	}
	public Map<String, Object> getFields()
	{
		return fields;
	}
	public Map<String, KintoneSubTable> getSubTables()
	{
		return subTables;
	}
	public void removeField(String fieldCode)
	{
		if(fields.containsKey(fieldCode))
		{
			fields.remove(fieldCode);
		}
	}
	public String getString(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? value.toString() :  null; 
	}
	public void setString(String fieldCode, String value)
	{
		fields.put(fieldCode, value);
	}
	public LocalDate getDate(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (LocalDate)value :  null; 
	}
	public void setDate(String fieldCode, LocalDate value)
	{
		fields.put(fieldCode, value);
	}
	public OffsetDateTime getOffsetDateTime(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (OffsetDateTime)value :  null;
	}
	public void setOffsetDateTime(String fieldCode, OffsetDateTime value)
	{
		fields.put(fieldCode, value);
	}
	public ZonedDateTime getZonedDateTime(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		if(value == null)
		{
			return null;
		}
		else if(value instanceof ZonedDateTime)
		{
			return (ZonedDateTime)value;
		}
		else
		{
			return ((OffsetDateTime)value).atZoneSameInstant(ZoneId.systemDefault());
		}
	}
	public void setZonedDateTime(String fieldCode, ZonedDateTime value)
	{
		fields.put(fieldCode, value);
	}
	public LocalTime getTime(String fieldCode)
	{
		
		Object value = fields.get(fieldCode);
		return value != null ? (LocalTime)value :  null;
	}
	public void setTime(String fieldCode, LocalTime value)
	{
		fields.put(fieldCode, value);
	}
	
	public Long getLong(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		if(value == null)
		{
			return null;
		}
		else if(value instanceof Integer)
		{
			return ((Integer)value).longValue();
		}
		else if(value instanceof BigDecimal)
		{
			return ((BigDecimal)value).longValue();
		}
		else
		{
			return (Long)value;
		}
	}
	
	public void setLong(String fieldCode, Long value)
	{
		fields.put(fieldCode, value);
	}
	
	public Integer getInt(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		
		if(value == null)
		{
			return null;
		}
		else if(value instanceof Long)
		{
			return ((Long)value).intValue();
		}
		else if(value instanceof BigDecimal)
		{
			return ((BigDecimal)value).intValue();
		}
		else
		{
			return (Integer)value;
		}
	}
	public void setInt(String fieldCode, Integer value)
	{
		fields.put(fieldCode, value);
	}
	public Double getDouble(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		
		if(value == null)
		{
			return null;
		}
		else if(value instanceof BigDecimal)
		{
			return ((BigDecimal)value).doubleValue();
		}
		else
		{
			return (Double)value;
		}
	}
	
	public void setDouble(String fieldCode, Double value)
	{
		fields.put(fieldCode, value);
	}
	
	public void setNumber(String fieldCode, BigDecimal value)
	{
		fields.put(fieldCode, value);
	}
	public Double getNumber(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		
		if(value == null)
		{
			return null;
		}
		else
		{
			return (Double)value;
		}
	}
	
	public KintoneUserMap getUsers(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (KintoneUserMap)value :  null;
	}
	
	public void setUsers(String fieldCode, KintoneUserMap value)
	{
		fields.put(fieldCode, value);
	}

	public KintoneGroupMap getGroups(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (KintoneGroupMap)value :  null;
	}
	
	public void setGroups(String fieldCode, KintoneGroupMap value)
	{
		fields.put(fieldCode, value);
	}
	public KintoneOrganizationMap getOrganizations(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (KintoneOrganizationMap)value :  null;
	}
	
	public void setOrganizations(String fieldCode, KintoneOrganizationMap value)
	{
		fields.put(fieldCode, value);
	}
	
	@SuppressWarnings("unchecked")
	public Set<String> getStringSet(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (Set<String>)value :  null;
	}
	public void setStringSet(String fieldCode, Set<String> value)
	{
		fields.put(fieldCode, value);
	}
	public void setUser(String fieldCode, CybozuUser user)
	{
		fields.put(fieldCode, user);
	}
	public CybozuUser getUser(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (CybozuUser)value :  null;
	}
	
	public KintoneFileList getFiles(String fieldCode)
	{
		Object value = fields.get(fieldCode);
		return value != null ? (KintoneFileList)value :  null;
	}
	public void setFiles(String fieldCode, KintoneFileList value)
	{
		fields.put(fieldCode, value);
	}
	
	public void setSubTable(String fieldCode, KintoneSubTable subTable)
	{
		subTables.put(fieldCode, subTable);
	}
	public KintoneSubTable getSubTable(String fieldCode)
	{
		Object value = subTables.get(fieldCode);
		return value != null ? (KintoneSubTable)value :  null;
	}
	public void removeSubTable(String fieldCode)
	{
		if(subTables.containsKey(fieldCode))
		{
			subTables.remove(fieldCode);
		}
	}
}
